#include "lightprocesser.h"
#include "controller.h"
//#include "lightingui.h"
#include "paramui.h"
#include "log4z.h"
#include "rs232.h"

pthread_t data_tid;

void* dataValidate(void* ptr)
{
    int cport_nr = 0,     /* /dev/ttyS1 (COM1 on windows) */
    bdrate= 57600;       /* 57600 baud */

    char mode[]={'8','N','1',0};
    unsigned char readBuf[8];
    memset(readBuf, 0, 8);

//    if(RS232_OpenComport(cport_nr, bdrate, mode))
//    {
//        return ((void *)0);
//    }
//    //int iDataCnt = 0;
    while (ParamUI::blValidate)
    {
        memset(readBuf, 0, 8);
        int iCnt = RS232_PollComport(cport_nr, readBuf, 8);
        //total data
        //iDataCnt += iCnt;
        if (iCnt >= 8)
        {
            std::string strBuf(reinterpret_cast<const char*>(readBuf), iCnt);
            LOGFMTD("Func %s: Size=%d, Buff=%s", __func__, iCnt, strBuf.c_str());
            //Light error
            if (readBuf[5] == 'R' && readBuf[6] == '0')
            {
                //error
                LightProcesser* lp = (LightProcesser*)(ptr);
                if (0 != lp)
                {
                    emit lp->statusChange(8002);
                }
                ParamUI::blValidate = false;
                break;
            }
            //Yaodong error
            else if (readBuf[5] == 'N' && readBuf[6] == '0')
            {
                //error
                LightProcesser* lp = (LightProcesser*)(ptr);
                if (0 != lp)
                {
                    emit lp->statusChange(8004);
                }
                ParamUI::blValidate = false;
                break;
            }
        }

        //LOGD("Running in data validation...");
        QThread::msleep(100);
    }
#ifdef INTERNAL_OPEN
    RS232_CloseComport(cport_nr);
#endif
    LOGD("exit in data validation...");

    return ((void *)0);
}

LightProcesser::LightProcesser(QObject *parent):QThread(parent)
  ,bLighting(false)
{

}

void LightProcesser::quitLight(bool bflag)
{
    bLighting = bflag;
    ParamUI::blValidate = false;
    pthread_join(data_tid, 0);
}

LightProcesser::~LightProcesser()
{

}

void LightProcesser::run()
{
    Controller gEttaCtrl;
    int iMaxWaitForIo = 60*10;
    int iFinalRet = 0;

    int iSlpT1 = ParamUI::fTimeSpan*33;
    int iSlpT2 = ParamUI::fTimeSpan*60;
    //jiance 2.58 = 4
    //3.96
    //5.14 = 6

    //Start lighting
    bLighting = true;

    LOGFMTD("Func %s, Now start the light process", __func__);
    float fSpd = ParamUI::qstrLiusu.toFloat()*1000/28;
    gEttaCtrl.SetLightPar(ParamUI::qstrDianya, ParamUI::qstrMaikuan,
                      ParamUI::qstrJiange, QString("%1").arg((int)fSpd));

    //Light function check
    int icRet = gEttaCtrl.LightShock();

    //Set light parameter
    if (icRet > 0)
    {
        //close the door
        icRet = gEttaCtrl.CloseDoor();
        if (icRet <= 0)
        {
            //Error UI
            emit statusChange(8001);
            return;
        }
    }
    else if (icRet == -1) // Pipe line error
    {
        //Error UI
        emit statusChange(8002);
        return;
    }
    else if (icRet == -3) // No Pipeline
    {
        //Error UI
        emit statusChange(8015);
        return;
    }
    else if (icRet == -4) // SHOCK
    {
        //Error UI
        emit statusChange(8012);
        return;
    }
    else if (icRet == -5) // SHOCK
    {
        //Error UI
        emit statusChange(8013);
        return;
    }
    else
    {
        //Error UI other error
        emit statusChange(8003);
        return;
    }

    //enable cancel and pause now
    emit statusChange(1);
    int iSt = gEttaCtrl.StartIo();
    int iTot = 0;
    if (iSt == 1)
    {
        //guiwei
        gEttaCtrl.SpeedMotor(1);
        gEttaCtrl.StartMotor();
        while (iSt == 1 && iTot++ <= 20)
        {
            QThread::msleep(200);
            iSt = gEttaCtrl.StartIo();
        }
        gEttaCtrl.StopMotor();
    }
    //Timeout
    if (iTot > 20)
    {
        //Error UI
        emit statusChange(8007);
        return;
    }
    icRet = gEttaCtrl.CloseYao();
    if (icRet <= 0)
    {
        //Error UI
        emit statusChange(8004);
        return;
    }
    icRet = gEttaCtrl.StartRuDong();
    if (icRet <= 0)
    {
        //Error UI
        emit statusChange(8003);
        return;
    }
    if (ParamUI::blYaodong)
    {
        icRet = gEttaCtrl.OpenYao();
        if (icRet <= 0 )
        {
            //Error UI yaodong
            emit statusChange(8004);
            return;
        }
    }

    LOGD("Start the Canliu IO check...");

    int iWaitTm = 0, iKeepTm = 0;
    //Check miss read
    iMaxWaitForIo = ParamUI::fTimeSpan*40;
    CheckCanLiu:
    iKeepTm = 0;
    int iCanLiu = gEttaCtrl.CanLiuIo();
    while (iCanLiu == 0 && iWaitTm++ <= iMaxWaitForIo)
    {
        iCanLiu = gEttaCtrl.CanLiuIo();
        //Check cancel
        if (!bLighting)
        {
            return;
        }
        QThread::msleep(100);
    }
    LOGFMTD("Canliu IO %d, wait times %d", iCanLiu, iWaitTm);
    if (iWaitTm >= iMaxWaitForIo && iCanLiu == 0)
    {
        //Error UI
        emit statusChange(8005);
        return;
    }
    //Check canliu keep 1 for more than 1000 ms
    while (iCanLiu == 1 && iKeepTm++ < 20)
    {
        iCanLiu = gEttaCtrl.CanLiuIo();
        //Check cancel
        if (!bLighting)
        {
            return;
        }
        QThread::msleep(50);
    }
    if (iKeepTm != 21)
    {
        goto CheckCanLiu;
    }

    LOGD("Now start light from process...");
    icRet = gEttaCtrl.StartLight();
    //One thread to reading data
    ParamUI::blValidate = true;

    int err = pthread_create(&data_tid, NULL, dataValidate, this);
    if(err != 0){
        //error
    }

    //Waitting to done
    //Check cancel
    if (!bLighting)
    {
        return;
    }

    CheckCanLiuStop:
    iKeepTm = 0;
    iCanLiu = gEttaCtrl.CanLiuIo();
    LOGD("Start the Canliu IO End check...");
    while (iCanLiu == 1)
    {
        QThread::msleep(200);
        iCanLiu = gEttaCtrl.CanLiuIo();
        if (!bLighting)
        {
            return;
        }
    }
    LOGD("Canliu IO == 0, check accurate...");
    //Check canliu keep 0 for more than 400 ms
    while (iCanLiu == 0 && iKeepTm++ < 20)
    {
        iCanLiu = gEttaCtrl.CanLiuIo();
        //Check cancel
        if (!bLighting)
        {
            return;
        }
        QThread::msleep(50);
    }
    if (iKeepTm != 21)
    {
        goto CheckCanLiuStop;
    }
    //Check cancel
    if (!bLighting)
    {
        return;
    }

    //then fanzhuan
    LOGFMTD("Now start turn over with %d...", iSlpT1);
    int iCnt = iSlpT1;
    while (iCnt-- >0)
    {
        if (!bLighting)
        {
            return;
        }
        QThread::msleep(100);
    }

    LOGD("Stop validation thread...");
    //stop validation
    ParamUI::blValidate = false;
    pthread_join(data_tid, 0);
    QThread::msleep(200);
    //Reset yaodong
    if (ParamUI::blYaodong)
    {
        icRet = gEttaCtrl.CloseYao();
    }
    LOGD("Now stop light...");
    //stop light
    icRet = gEttaCtrl.StopLight();
    if (icRet <= 0)
    {
        //Error UI
        iFinalRet = 8010;
    }

    //Check cancel
    if (!bLighting)
    {
        return;
    }

    LOGD("Speed and start motor...");
    icRet = gEttaCtrl.SpeedMotor(2);
    icRet = gEttaCtrl.StartMotor();
    //check stop position

    LOGD("Check Stop Io...");
    int iRet = gEttaCtrl.StopIo();
    iWaitTm = 0;
    while (iRet == 1 && iWaitTm++ <= iMaxWaitForIo)
    {
        QThread::msleep(200);
        iRet = gEttaCtrl.StopIo();
        if (!bLighting)
        {
            return;
        }
    }
    LOGFMTD("Stop IO %d, wait times %d", iRet, iWaitTm);
    if (iWaitTm >= iMaxWaitForIo && iRet == 1)
    {
        //Error UI
        emit statusChange(8007);
        return;
    }

    LOGD("Now stop the motor...");
    //stop and get back
    iRet = gEttaCtrl.StopMotor();
    iCnt = iSlpT2;
    while (iCnt-- >0)
    {
        if (!bLighting)
        {
            return;
        }
        QThread::msleep(100);
    }

    //Check cancel
    if (!bLighting)
    {
        return;
    }

    LOGD("Now stop ru dong...");

    iRet = gEttaCtrl.StopRuDong();
    if (iRet <= 0)
    {
        emit statusChange(8003);
        return;
    }
    //Check cancel
    if (!bLighting)
    {
        return;
    }

    LOGD("Now turn back motor...");
    iRet = gEttaCtrl.SpeedMotor(1);
    iRet = gEttaCtrl.StartMotor();
    //check start position
    iRet = gEttaCtrl.StartIo();
    iWaitTm = 0;
    while (iRet == 1 && iWaitTm++ <= iMaxWaitForIo)
    {
        QThread::msleep(200);
        iRet = gEttaCtrl.StartIo();
        //Check cancel
        if (!bLighting)
        {
            return;
        }
    }
    LOGFMTD("Start IO %d, wait times %d", iRet, iWaitTm);
    if (iWaitTm >= iMaxWaitForIo && iRet == 1)
    {
        //Error UI
        emit statusChange(8007);
        return;
    }
    //stop motor
    iRet = gEttaCtrl.StopMotor();
    //we are done
    //Check cancel
    if (!bLighting)
    {
        return;
    }
    //Open the door
    icRet = gEttaCtrl.OpenDoor();
    if (icRet <= 0)
    {
        //Error UI open door failed
        //Error UI
        emit statusChange(8001);
        return;
    }
    LOGD("Whole process is over...");

    emit statusChange(iFinalRet);
}
